<script setup lang="ts">
import { Api, CondProps, format, useLoading } from '@idmy/core'
import { isNil, isNumber } from 'lodash-es'
import { computed, isVNode, PropType, reactive, ref } from 'vue'
import { Button, Form, FormItem, Input, Pagination, Space, Table } from 'ant-design-vue'
import { Modal, ModalButton } from '../modal'
import View from '../view/index.vue'

defineOptions({ name: 'ModalPicker', inheritAttrs: false })

const props = defineProps({
	api: { type: Function, required: true },
	columns: { type: Array, required: true },
	cond: {
		type: Object as PropType<any>,
		default: () => ({
			col: 3,
			reset: true,
		}),
	},
	conds: { type: Array as PropType<CondProps[]>, default: () => [] },
	height: { type: [String, Number], default: 341 },
	immediate: { type: Boolean, default: true },
	multiple: { type: Boolean, default: true },
	rowKey: { type: String, required: true },
	selectedKeys: { type: Array, default: () => [] },
	showSelected: { type: Boolean, default: true },
	span: { type: Number, default: 15 },
	type: { type: String as PropType<'Page' | 'Array'>, default: 'Page' },
})

const height = computed(() => (isNumber(props.height) ? `${props.height}px` : props.height))

const showSelected = computed(() => props.showSelected && props.multiple)

const selection = reactive<any>({
	fixed: true,
	onChange(keys: any[], rows: any[]) {
		selection.selectedRowKeys = keys
		selection.selectedRows = rows
		setTimeout(() => {
			props.immediate && !props.multiple && onOk()
		}, 300)
	},
	preserveSelectedRowKeys: true,
	selectedRowKeys: [],
	selectedRows: [],
	showCheckedAll: true,
	type: props.multiple ? 'checkbox' : 'radio',
})

const selectedColumns = computed(() => {
	return _columns.value.filter(item => {
		return item.selected
	})
})

const load = async (args: any) => {
	const tmp = await props.api(args)
	return tmp.data ?? tmp
}

const [, selectedLoading] = useLoading(async () => {
	const { selectedKeys } = props
	if (selectedKeys.length) {
		const { list } = await load({
			cond: { [`${props.rowKey}s`]: selectedKeys },
			pageNo: 1,
			pageSize: selectedKeys.length,
		})
		selection.selectedRows = list
		selection.selectedRowKeys = selectedKeys
	}
}, showSelected.value)

const _columns = computed(() => {
	return props.columns.map((item: any) => {
		if (!item.customRender) {
			item.customRender = ({ text }: any) => {
				return format(text, item.format ?? item.type, item.params)
			}
		}
		if (isNil(item.ellipsis)) {
			item.ellipsis = true
		}
		if (isNil(item.tooltip)) {
			item.tooltip = true
		}
		return item
	})
})

const onOk = () => {
	const { selectedRowKeys, selectedRows } = selection
	Modal.e.ok(selectedRows, selectedRowKeys)
}

const formRef = ref()
const onReset = () => {
	formRef.value.resetFields()
}
const minWidth = computed(() => (parseInt(Modal.e.width.value as string) - 56) / 24)
</script>

<template>
	<Api v-slot="{ input, output, loading, onLoad, onSort }" :load="load" :type="type" :rowKey="rowKey">
		<div class="dmy-antd-modal-picker">
			<template v-if="type === 'Page' && conds.length">
				<div class="df jcsb">
					<Form ref="formRef" :model="input.params" class="f1" :colon="false" @finish="onLoad()">
						<div class="dg" :style="`grid-template-columns: repeat(${cond.col}, 1fr); column-gap: 8px`">
							<FormItem v-for="cond in conds" :key="cond.field" :label="cond.title" :name="cond.field">
								<component :is="cond.component" v-if="isVNode(cond.component)" />
								<Input v-else v-model:value="input.params[cond.field]" allow-clear />
							</FormItem>
							<FormItem v-if="conds.length < cond.col">
								<Space>
									<Button type="primary" html-type="submit">查询</Button>
									<Button v-if="cond.reset" @click.stop="onReset(), onLoad()">重置</Button>
								</Space>
							</FormItem>
						</div>
					</Form>
					<div v-if="conds.length >= cond.col" class="df fdc" style="gap: 8px; width: 60px; margin-left: 8px">
						<Button v-if="cond.reset" @click.stop="onReset()">重置</Button>
						<Button type="primary" @click.stop="onLoad()">查询</Button>
					</div>
				</div>
			</template>
			<div class="df" :style="showSelected ? `gap: 16px` : undefined">
				<div :style="{ maxWidth: minWidth * (showSelected ? span : 24) + 'px' }">
					<View :title="`所有数据(${(output as any).total})`" v-if="showSelected" />
					<Table
						:scroll="{ x: minWidth * (showSelected ? span : 24) - 20 + 'px', y: height }"
						bordered
						:row-selection="selection as any"
						size="small"
						:row-key="rowKey"
						:columns="_columns"
						:data-source="type === 'Page' ? (output as any)?.list : output"
						:loading="loading"
						:pagination="false"
						@change="(_p: any, _f: any, s: any) => onSort(s)"
					/>
				</div>
				<div v-if="showSelected" :style="{ maxWidth: minWidth * (24 - span) + 'px' }">
					<View :title="`已选数据(${selection.selectedRowKeys.length})`" />
					<Table
						bordered
						:scroll="{ y: height }"
						:row-selection="selection as any"
						size="small"
						:row-key="rowKey"
						:columns="selectedColumns"
						:data-source="selection.selectedRows"
						:loading="selectedLoading"
						:pagination="false"
					/>
				</div>
			</div>
			<div class="df jcsb aic" style="margin-top: 8px">
				<Pagination v-model:current="input.pageNo" :total="(output as any).total" simple @change="onLoad()" v-if="type === 'Page'" />
				<div v-else />
				<ModalButton @ok="onOk()" :ok-disabled="!multiple && !selection.selectedRowKeys.length" />
			</div>
		</div>
	</Api>
</template>
